package com.web_bloks.project.controllers.client;

import java.util.Iterator;
import java.util.Vector;

import com.web_bloks.document.client.Document;
import com.web_bloks.document.client.DocumentListener;
import com.web_bloks.document.client.Title;

import com.web_bloks.html.client.FormHelper;
import com.web_bloks.html.client.HtmlException;
import com.web_bloks.http.client.PostHttpCall;

import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.RequestCallback;
import com.google.gwt.http.client.RequestException;

import com.google.gwt.http.client.Response;

import com.web_bloks.system.client.Logger;

/**
 * 
 * @author Jean-Lou Dupont
 *
 */
public class PostController 
	implements RequestCallback, DocumentListener {

	public final static int STATE_ERROR_NETWORK = 0;
	public final static int STATE_ERROR_HTML 	= 1;
	
	Vector<PostListener> listeners = new Vector<PostListener>();
	
	PostHttpCall poster = new PostHttpCall();
	
	String api = null;
	String eid = null;
	
	Title currentDocTitle = null;
	boolean currentDocValid = false;
	
	/*========================================================
	 * Constructors
	 ========================================================*/
	public PostController() {
		poster.setRequestCallback(this);
	}
	/*========================================================
	 * Configuration
	 ========================================================*/
	public void setElementId(String eid) {
		this.eid = new String( eid );
	}
	public void setApi(String api) {
		this.api = new String( api );
	}
	/*========================================================
	 * API
	 ========================================================*/
	public void execute() {
		
		if (isPending())
			return;
		
		if (!currentDocValid) {
			Logger.logWarn(getClass()+".execute: tried posting an invalid doc");
			return;
		}
		String content = null;
		
		// retrieve & serialize content data
		try {
			content = FormHelper.serialize(eid);
		} catch(HtmlException e) {
			Logger.logError(getClass()+".execute: HtmlException, msg="+e.getMessage());
			notifyListeners( STATE_ERROR_HTML );
			return;
		}
		Logger.logInfo(getClass()+".execute, content=" + content);
		// post action
		try {
			poster.execute(api+currentDocTitle.toString()+"/", content);
		} catch(RequestException e) {
			Logger.logError(getClass()+".execute: RequestException, msg="+e.getMessage());
			notifyListeners(STATE_ERROR_NETWORK);
			return;
		}
		
	}
	public void cancel() {
		poster.cancel();
	}
	public boolean isPending() {
		return poster.isPending();
	}
	/*===================================================================
	 * Listeners 
	 ===================================================================*/
	public void addListener( PostListener listener ) {
		listeners.add( listener );
	}
	public void removeListener( PostListener listener ) {
		listeners.remove(listener);
	}
	protected void notifyListeners(int code) {
		Logger.logInfo( getClass()+".notifyListeners");
		
		Iterator<PostListener> it = this.listeners.iterator();
		while (it.hasNext()) {
			Object o = it.next ();
		    ((PostListener) o).onPostCompleted( code );
		}
	}
	/*========================================================
	 * REQUESTCALLBACK
	 ========================================================*/
	public void onError(Request request, java.lang.Throwable exception ) {
		Logger.logInfo( getClass()+".onError");
		notifyListeners( 0 );
	}
	
	public void onResponseReceived(Request request, Response response) {
		int code = response.getStatusCode();
		
		Logger.logInfo( getClass()+".onResponseReceived, code=" + code);
		
		notifyListeners( code );
	}
	/*========================================================
	 * DocumentListener
	 ========================================================*/
	public void onDocumentChanging(String name, String targetRegionName) {
		//nothing todo really
	}
	/**
	 * Grab the doc name for *if* and *when* 
	 * we are asked to perform a POST.
	 */
	public boolean onDocumentChanged(Document doc) {
		
		if ( null == doc ) {
			currentDocTitle = null;
			currentDocValid = false;
		} else {
			currentDocTitle = doc.getPageTitle();
			currentDocValid = doc.getState() == Document.STATE_VALID;
		}
		
		//not rendered.
		return false;
	}

	public void onDocumentRendered(Document doc) {		
	}
}//END